import re
import time
import os, sys
from Cookie import SimpleCookie
import json
from pprint import pprint
import aws
import base64
import hmac, hashlib

def simple_print(state, out_str):
    state.tmpl.load('plain.html')
    tmpl_add_defaults(state)
    state.tmpl.substitute({"cnt":out_str})
    print state.tmpl.get_html()

def delete(state):
    delete_confirmed = state.form.getvalue('delete_confirmed', False)
    key_name = state.form.getvalue('key_name', None)
    if not key_name:
        list(state)
        return None
    if delete_confirmed:
        state.aws.b.delete_key(key_name)
        list(state)
        return None
    print "Content-type: text/html\n\n"
    out_str = "Are you sure you want to delete this file?<br><br>"
    url = "%sdelete/?key_name=%s&delete_confirmed=True" % (state.request_base_uri, key_name)
    out_str += "<a href='%s'>Yes, delete it.</a><br><br>" % url
    out_str += "<a href='%s'>No, Do NOT delete it.</a>" % (state.request_base_uri + 'list')
    simple_print(state, out_str)
    
    
def debug(state):
    print "Content-type: text/html\n\n"
    print "Whoo Hoo, we made it here."
    print "<h1>Form Vars</h1><pre>"
    for k in state.form.keys():
        print "%s = %s" %(k, state.form.getvalue(k))
    print "<h1>State Computed Values</h1><pre>"
    for k in 'request_uri,request_url,request_base_uri,request_base_url'.split(','):
        print '%s = %s' % (k, getattr(state, k, "not found"))
    if 'HTTP_V' in os.environ:
        print "</pre><h1>Json Decoded</h1><pre>"
        v_string = os.environ.get('HTTP_V')
        v_data = json.loads(v_string)
        pprint(v_data)
    
    print "</pre><h1>OS Environ</h1><pre>"
    for k in os.environ.keys():
        print "%s = %s" % (k, os.environ[k])
    print "</pre>"

def whoami(state):
    print "Content-type: text/plain\n\n"
    print str(state.sess.uid)

def default(state):
    list(state)
    return None

     
def upload(state):
    
    opts_dict = {
        'bucket_name': state.aws.BUCKET_NAME,
        'awsaccesskeyid': state.aws.AWS_ID,
        'acl': 'private',
        'key_prefix': 'inbox/',
        'redirect_to': state.request_base_url + 'success/',
        }

    # construct upload policy
    # Every field in the upload form must be included here except
    # policy, signature, awsaccesskeyid, and file
    policy_dict = {
        'expiration': state.aws.get_iso_time(),
        'conditions': [
            {'acl': 'private'},
            {'bucket': state.aws.BUCKET_NAME },
            ['starts-with', '$key', opts_dict['key_prefix']],
            ['starts-with', '$success_action_redirect', opts_dict['redirect_to']],
            ['starts-with', '$x-amz-meta-username', ''],
            ['starts-with', '$x-amz-meta-customer', ''],
            ['starts-with', '$x-amz-meta-filename', ''],
            ]
        }
    policy_str = json.dumps(policy_dict, encoding='utf-8')
    policy_base64 = base64.b64encode(policy_str)
    policy_hmac = hmac.new(state.aws.AWS_KEY, policy_base64, hashlib.sha1)
    policy_sign = policy_hmac.digest()
    unique = policy_hmac.hexdigest()
    policy_sign_base64 = base64.b64encode(policy_sign)
    
    opts_dict['unique'] = unique
    opts_dict['policy'] = policy_base64
    opts_dict['signature'] = policy_sign_base64   
    
    new_key_name = '%s%s' % (opts_dict['key_prefix'],opts_dict['unique'])
    k = state.aws.b.get_key(new_key_name)

    if k:
        if not getattr(state, 'exists_loop', None):
            state.exists_loop = 1
        elif state.exists_loop == 15:
            print "Content-type: text/html\n\n"
            print "Error, Looped 15 times"
            return None
        else:
            state.exists_loop = state.exists_loop + 1
        upload(state)
        return None
    
    state.tmpl.load('base.html')
    tmpl_add_defaults(state)
    state.tmpl.substitute(opts_dict)
    print "Content-type: text/html\n\n"
    print state.tmpl.get_html()

def success(state):
    print "Content-type: text/html\n\n"
    cnt = "Successfully uploaded file, click here to view them."
    cnt += "<a href='%s'>%s</a>" % (state.request_base_url + 'list', 'list')
    simple_print(state, cnt)
    
    
def tmpl_add_defaults(state):
    defaults = {
        'upload_url': state.request_base_url + 'upload/',
        'list_url': state.request_base_url + 'list/'
        }
    state.tmpl.add_defaults(defaults)
    
def list(state, print_header=True):
    import time, urllib, base64, hmac, hashlib, re            
    if print_header:
        print "Content-type: text/html\n\n"
    
    out_str = "<table cellspacing=0 cellpadding=0><tr><th>Uploaded By</th>"\
            "<th>For Customer</th><th>Date</th><th>Size</th><th>Download</th>"\
            "<th>Delete</th></tr>"
    expires = int(time.time() )+ 30 * 60
    for k in state.aws.b.list('inbox/'):
        k = state.aws.b.get_key(k.name)
        name = urllib.quote(k.name)
               
        string_to_sign = u"GET\n\n\n%s\n/%s/%s" % (expires, state.aws.BUCKET_NAME, name)
        signature = base64.encodestring(hmac.new(state.aws.AWS_KEY, string_to_sign, hashlib.sha1).digest()).strip()
    	signature = urllib.quote(signature)

          
        url = "http://%s.s3.amazonaws.com/%s?AWSAccessKeyId=%s&Expires=%s&Signature=%s" % (
                    state.aws.BUCKET_NAME, 
                    name,
                    state.aws.AWS_ID,
                    expires,
                    signature)
                    
        delete_url = "<a href='%sdelete/?key_name=%s'>del</a>" % (state.request_base_uri, name)
        
        out_str += "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>"\
                "<a href='%s'>%s</a></td><td>%s</td></tr>" % (
                    k.get_metadata('username'),
                    k.get_metadata('customer'),
                    k.last_modified,
                    k.size,
                    url,
                    k.get_metadata('filename'),
                    delete_url
                    )
        #print "<a href='%s'>%s</a>, user: %s, cust: %s, size: %s, modified: %s" % (url, k.get_metadata('filename'), k.get_metadata('username'), k.get_metadata('customer'), k.size, k.last_modified)
        
    out_str += "</table>"
    simple_print(state, out_str)
    
